package demo1;

class B{

  public B() {//父类的构造方法
   func();//这时候调用的是子类的重写方法func
  }
  public void func(){
   System.out.println(" B.func() ");
  }
}
class D extends B{
  private int num = 1;
  public D(){//子类的构造方法。两者都没有写参数，所以子类可以不用写
      super();
  }
 @Override
 public void func() {
  System.out.println(" D.func() " + num);
 }
}
public class Test2 {
    public static void main(String[] args) {
        D d = new D();
    }
    /*
    我的理解：
    //这个是时候我们打印的是 D.func() 0
    //首先我们知道先执行的是构造方法，然后再是属性行为
    //是因为我们当去进行扫描的时候会发现，父类B到了构造方法的时候，存在func()，等到了D的构造方法的时候先帮助父类进行构造
    //这个时候调用的是子类的重写的方法，多态，但是为什么会打印的0呢
    //这是因为这个时候还没有帮助子类D没有构造完成（其实也是没有走到子类D，才帮助父类构造),所以num没有进行初始化
    //将num进行了赋值0的初始化，所以会打印的是 D.func() 0
     */

    //他人理解：
    //构造 D 对象的同时, 会调用 B 的构造方法.
    //B 的构造方法中调用了 func 方法, 此时会触发动态绑定, 会调用到 D 中的 func
    //此时 D 对象自身还没有构造, 此时 num 处在未初始化的状态, 值为 0. 如果具备多态性，num的值应该是1.
    //所以在构造函数内，尽量避免使用实例方法，除了ﬁnal和private方法。
}